package org.example.ding.entity;

import jakarta.persistence.*;
import jakarta.validation.constraints.*;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.AllArgsConstructor;
import com.fasterxml.jackson.annotation.JsonIgnore;
import org.hibernate.annotations.CreationTimestamp;
import org.hibernate.annotations.UpdateTimestamp;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;

/**
 * 用户实体类
 * 包含用户基本信息、营养目标和饮食偏好
 */
@Entity
@Table(name = "users")
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(unique = true, nullable = false, length = 50)
    @NotBlank(message = "用户名不能为空")
    @Size(min = 3, max = 50, message = "用户名长度必须在3-50个字符之间")
    private String username;

    @Column(nullable = false)
    @NotBlank(message = "密码不能为空")
    @Size(min = 6, message = "密码长度至少6个字符")
    @JsonIgnore
    private String password;

    @Column(unique = true, length = 100)
    @Email(message = "邮箱格式不正确")
    private String email;

    @Column(name = "real_name", length = 50)
    @Size(max = 50, message = "真实姓名长度不能超过50个字符")
    private String realName;

    @Enumerated(EnumType.STRING)
    private Gender gender;

    @Min(value = 1, message = "年龄必须大于0")
    @Max(value = 150, message = "年龄不能超过150")
    private Integer age;

    @DecimalMin(value = "0.0", message = "身高必须大于0")
    @DecimalMax(value = "300.0", message = "身高不能超过300cm")
    @Column(precision = 5, scale = 2)
    private BigDecimal height;

    @DecimalMin(value = "0.0", message = "体重必须大于0")
    @DecimalMax(value = "1000.0", message = "体重不能超过1000kg")
    @Column(precision = 5, scale = 2)
    private BigDecimal weight;

    @Enumerated(EnumType.STRING)
    @Column(name = "activity_level")
    private ActivityLevel activityLevel = ActivityLevel.MODERATE;

    // 营养目标
    @DecimalMin(value = "0.0", message = "卡路里目标必须大于0")
    @Column(name = "daily_calories_goal", precision = 8, scale = 2)
    private BigDecimal dailyCaloriesGoal = new BigDecimal("2000");

    @DecimalMin(value = "0.0", message = "蛋白质目标必须大于0")
    @Column(name = "daily_protein_goal", precision = 8, scale = 2)
    private BigDecimal dailyProteinGoal = new BigDecimal("150");

    @DecimalMin(value = "0.0", message = "碳水化合物目标必须大于0")
    @Column(name = "daily_carbs_goal", precision = 8, scale = 2)
    private BigDecimal dailyCarbsGoal = new BigDecimal("250");

    @DecimalMin(value = "0.0", message = "脂肪目标必须大于0")
    @Column(name = "daily_fat_goal", precision = 8, scale = 2)
    private BigDecimal dailyFatGoal = new BigDecimal("65");

    // 饮食限制和过敏信息 (JSON格式存储)
    @Column(name = "dietary_restrictions", columnDefinition = "JSON")
    private String dietaryRestrictions;

    @Column(columnDefinition = "JSON")
    private String allergies;

    @CreationTimestamp
    @Column(name = "created_at", updatable = false)
    private LocalDateTime createdAt;

    @UpdateTimestamp
    @Column(name = "updated_at")
    private LocalDateTime updatedAt;

    @Column(name = "is_active")
    private Boolean isActive = true;

    // 关联关系
    @OneToMany(mappedBy = "user", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    @JsonIgnore
    private List<OrderRecord> orderRecords;

    // 移除了UserPreference和DailyNutritionSummary的关联，简化数据模型

    /**
     * 性别枚举
     */
    public enum Gender {
        MALE("男"),
        FEMALE("女"),
        OTHER("其他");

        private final String description;

        Gender(String description) {
            this.description = description;
        }

        public String getDescription() {
            return description;
        }
    }

    /**
     * 活动水平枚举
     */
    public enum ActivityLevel {
        SEDENTARY("久坐", 1.2),
        LIGHT("轻度活动", 1.375),
        MODERATE("中度活动", 1.55),
        ACTIVE("高度活动", 1.725),
        VERY_ACTIVE("极高活动", 1.9);

        private final String description;
        private final double multiplier;

        ActivityLevel(String description, double multiplier) {
            this.description = description;
            this.multiplier = multiplier;
        }

        public String getDescription() {
            return description;
        }

        public double getMultiplier() {
            return multiplier;
        }
    }

    /**
     * 计算基础代谢率 (BMR)
     * 使用Mifflin-St Jeor方程
     */
    public BigDecimal calculateBMR() {
        if (height == null || weight == null || age == null || gender == null) {
            return BigDecimal.ZERO;
        }

        double bmr;
        if (gender == Gender.MALE) {
            bmr = 10 * weight.doubleValue() + 6.25 * height.doubleValue() - 5 * age - 161;
        } else {
            bmr = 10 * weight.doubleValue() + 6.25 * height.doubleValue() - 5 * age - 161;
        }

        return BigDecimal.valueOf(bmr);
    }

    /**
     * 计算每日总能量消耗 (TDEE)
     */
    public BigDecimal calculateTDEE() {
        BigDecimal bmr = calculateBMR();
        double multiplier = activityLevel != null ? activityLevel.getMultiplier() : 1.55;
        return bmr.multiply(BigDecimal.valueOf(multiplier));
    }

    /**
     * 计算BMI
     */
    public BigDecimal calculateBMI() {
        if (height == null || weight == null) {
            return BigDecimal.ZERO;
        }
        
        BigDecimal heightInMeters = height.divide(BigDecimal.valueOf(100), 2, BigDecimal.ROUND_HALF_UP);
        return weight.divide(heightInMeters.multiply(heightInMeters), 2, BigDecimal.ROUND_HALF_UP);
    }
}
